package wypozyczalnia.mbeans;

import java.io.ByteArrayInputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.UploadedFile;

import wypozyczalnia.domain.Genre;
import wypozyczalnia.domain.Movie;
import wypozyczalnia.domain.Person;
import wypozyczalnia.domain.Photo;
import wypozyczalnia.forms.EditPersonForm;
import wypozyczalnia.service.MovieService;
import wypozyczalnia.service.PersonService;
import wypozyczalnia.service.PhotoService;

@ManagedBean(name = "personMBean")
@SessionScoped
public class PersonBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private List<Person> persons;
	private Person selectedPerson;
	private EditPersonForm editPersonForm = null;
	private List<Movie> movies;
	private List<String> selectedMovies;
	private Person searchedPerson;
	private String personPattern;
	private Map<String, UploadedFile> uploadedFiles;
	private List<String> listImages;

	@ManagedProperty("#{personService}")
	private PersonService personService;

	@ManagedProperty("#{movieService}")
	private MovieService movieService;

	@ManagedProperty("#{photoService}")
	private PhotoService photoService;

	public List<String> getSelectedMovies() {
		return this.selectedMovies;
	}

	public void setSelectedMovies(List<String> selectedMovies) {
		this.selectedMovies = selectedMovies;
	}

	public List<Movie> getMovies() {
		this.movies = this.movieService.getAllMovies();
		return this.movies;
	}

	public void setMovies(List<Movie> movies) {
		this.movies = movies;
	}

	public MovieService getMovieService() {
		return this.movieService;
	}

	public void setMovieService(MovieService movieService) {
		this.movieService = movieService;
	}

	public List<Person> getPersons() {
		this.persons = new ArrayList();
		this.persons = this.personService.getAllPersons();
		return this.persons;
	}

	public void setPersons(List<Person> persons) {
		this.persons = persons;
	}

	public Person getSelectedPerson() {
		return this.selectedPerson;
	}

	public void setSelectedPerson(Person selectedPerson) {
		this.selectedPerson = selectedPerson;
	}

	public EditPersonForm getEditPersonForm() {
		if (this.editPersonForm == null) {
			this.editPersonForm = new EditPersonForm();
		}
		return this.editPersonForm;
	}

	public void setEditPersonForm(EditPersonForm p_editPersonForm) {
		this.editPersonForm = p_editPersonForm;
	}

	public PersonService getPersonService() {
		return this.personService;
	}

	public void setPersonService(PersonService p_PersonService) {
		this.personService = p_PersonService;
	}

	public String dolistPerson() {
		return "listPerson";
	}

	public String listPerson() {
		return null;
	}

	public String doAddPerson() {
		selectedMovies = new ArrayList<String>();
		return "addPerson";
	}

	public String addPerson() {
		Person person = new Person(this.editPersonForm.getName(),
				this.editPersonForm.getSurname(),
				this.editPersonForm.getDescription(),
				this.editPersonForm.getBirthDate(),
				this.editPersonForm.getNationality());

		
		person.setMovie(movieService.getMoviesByIds(this.selectedMovies));
		
		this.personService.create(person);
		List photos = new ArrayList();
		if (this.listImages != null) {
			for (String key : this.listImages) {
				Photo p = new Photo();
				UploadedFile f = (UploadedFile) this.uploadedFiles.get(key);
				p.setMainPhoto(Boolean.valueOf(true));
				p.setPhoto(f.getContents());
				p.setPerson(person);
				photos.add(p);
			}
		}

		this.photoService.addPhotos(photos);

		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Sukces: ", "Dodano aktora!");

		FacesContext.getCurrentInstance().addMessage(null, message);

		return "listPerson";
	}
	
	public String editPerson() {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();

		String personId = (String) externalContext.getRequestParameterMap().get(
				"personId");

		this.selectedPerson = this.personService.getPerson(Integer
				.valueOf(Integer.parseInt(personId)));
		selectedMovies = new ArrayList<String>();
		for (Movie m : selectedPerson.getMovie()) {
			selectedMovies.add(m.getIdMovie().toString());
		}
		this.listImages = new ArrayList();
		this.uploadedFiles = new HashMap();

		return "editPerson";
	}
	
	public String saveEditedPerson() {
		List<Photo> photos = new ArrayList();
		if (this.listImages != null) {
			for (String key : this.listImages) {
				Photo p = new Photo();
				UploadedFile f = (UploadedFile) this.uploadedFiles.get(key);
				p.setMainPhoto(Boolean.valueOf(true));
				p.setPhoto(f.getContents());
				photos.add(p);
				p.setPerson(this.selectedPerson);
			}
		}
		if (!photos.isEmpty()) {
			this.photoService.addPhotos(photos);
			if (selectedPerson.getPhotos() == null) {
				selectedPerson.setPhotos(photos);
			} else {
				this.selectedPerson.getPhotos().addAll(photos);
			}
		}
		this.selectedPerson.setMovie(this.movieService
				.getMoviesByIds(this.selectedMovies));
		this.personService.updatePerson(this.selectedPerson);
		
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Sukces: ", "Zapisano zmiany");

		FacesContext.getCurrentInstance().addMessage(null, message);
		
		return null;
	}
	
	public StreamedContent getImage() {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();

		if (FacesContext.getCurrentInstance().getRenderResponse()) {
			// So, we're rendering the view. Return a stub StreamedContent so
			// that it will generate right URL.
			return new DefaultStreamedContent();
		} else {
			String imageId = (String) externalContext.getRequestParameterMap()
					.get("imageIdD");
			Photo p = null;
			if (selectedPerson.getPhotos() != null) {
				for (Photo photo : selectedPerson.getPhotos()) {
					if (photo.getIdPhoto().toString().equals(imageId)) {
						p = photo;
					}
				}
			}
			StreamedContent image = null;
			if (p != null) {
				image = new DefaultStreamedContent(new ByteArrayInputStream(
						p.getPhoto()), "image/png");

				return image;
			}
		}

		return null;
	}
	
	public String deleteActualPhoto() {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();

		String imageId = (String) externalContext.getRequestParameterMap().get(
				"imageIdD");

		photoService.deleteById(Integer.parseInt(imageId));
		int i = 0;
		for (Photo p : selectedPerson.getPhotos()) {
			if (p.getIdPhoto().toString().equals(imageId)) {
				break;
			}
			i++;
		}
		selectedPerson.getPhotos().remove(i);
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Sukces: ", "Usunięto obraz z listy");

		FacesContext.getCurrentInstance().addMessage(null, message);

		return "";
	}
	
	public String deletePhoto() {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();

		String imageId = (String) externalContext.getRequestParameterMap().get(
				"imageId");
		uploadedFiles.remove(imageId);
		listImages.remove(imageId);
		
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Sukces: ", "Usunięto obraz z listy");

		FacesContext.getCurrentInstance().addMessage(null, message);

		return "";

	}
	

	public List<String> complete(String query) {
		List results = new ArrayList();
		List<Person> allPersons = getPersons();
		for (Person person : allPersons) {
			if ((person.getName().contains(query))
					|| (person.getSurname().contains(query))
					|| (person.getNationality().contains(query))) {
				results.add(person.getSurname() + " " + person.getName() + " "
						+ person.getNationality());
			}

		}

		return results;
	}

	public void upload(FileUploadEvent event) {
		FacesMessage msg = new FacesMessage("Success! ", event.getFile()
				.getFileName() + " is uploaded.");

		FacesContext.getCurrentInstance().addMessage(null, msg);
		UploadedFile file = event.getFile();
		String key = file.getFileName();
		if (this.uploadedFiles == null) {
			this.uploadedFiles = new HashMap();
		}
		this.uploadedFiles.put(key, file);
		if (this.listImages == null) {
			this.listImages = new ArrayList();
		}
		this.listImages.add(key.toString());
	}

	public String selectedPersonAction(Integer p) {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();

		String personId = (String) externalContext.getRequestParameterMap()
				.get("personId");

		this.selectedPerson = this.personService.getPerson(Integer
				.parseInt(personId));
		return null;
	}

	public List<String> getListImages() {
		return this.listImages;
	}

	public void setListImages(List<String> listImages) {
		this.listImages = listImages;
	}

	public Map<String, UploadedFile> getUploadedFiles() {
		return this.uploadedFiles;
	}

	public void setUploadedFiles(Map<String, UploadedFile> uploadedFiles) {
		this.uploadedFiles = uploadedFiles;
	}

	public String doEditPerson() {
		ExternalContext externalContext = FacesContext.getCurrentInstance()
				.getExternalContext();

		String personId = (String) externalContext.getRequestParameterMap()
				.get("personId");

		return null;
	}

	public Person getSearchedPerson() {
		return this.searchedPerson;
	}

	public void setSearchedPerson(Person searchedPerson) {
		this.searchedPerson = searchedPerson;
	}

	public String getPersonPattern() {
		return this.personPattern;
	}

	public void setPersonPattern(String personPattern) {
		this.personPattern = personPattern;
	}

	public void setPhotoService(PhotoService photoService) {
		this.photoService = photoService;
	}

}
